/**
 * @description:树形结构转一维数组
 * @param {*} nodes
 * @return {*}
 */
export function jsonToArray(nodes) {
    let pid = -1;
    const toArray = (nodes) => {
        let r = [];
        if (Array.isArray(nodes)) {
            for (let i = 0, l = nodes.length; i < l; i++) {
                nodes[i].pid = pid;
                r.push(nodes[i]); // 取每项数据放入一个新数组
                if (
                    Array.isArray(nodes[i]["children"]) &&
                    nodes[i]["children"].length > 0
                ) {
                    // 若存在children则递归调用，把数据拼接到新数组中，并且删除该children
                    pid = nodes[i].id;
                    r = r.concat(toArray(nodes[i]["children"]));
                    delete nodes[i]["children"];
                }
            }
        }
        return r;
    };
    return toArray(nodes);
}

/**
 * @description:一维数组转树形结构
 * @param {*} treeArray
 * @return {*}
 */
export function arrayToJson(treeArray) {
    var r = [];
    var tmpMap = {};
    for (var i = 0, l = treeArray.length; i < l; i++) {
        //* 以每条数据的id作为obj的key值，数据作为value值存入到一个临时对象里面
        tmpMap[treeArray[i]["id"]] = treeArray[i];
    }
    for (i = 0, l = treeArray.length; i < l; i++) {
        var key = tmpMap[treeArray[i]["pid"]];
        //*循环每一条数据的pid，假如这个临时对象有这个key值，就代表这个key对应的数据有children，需要Push进去
        //*如果这一项数据属于哪个数据的子级
        if (key) {
            // *如果这个数据没有children
            if (!key["children"]) {
                key["children"] = [];
                key["children"].push(treeArray[i]);
                //* 如果这个数据有children
            } else {
                key["children"].push(treeArray[i]);
            }
        } else {
            //*如果没有这个Key值，就代表找不到属于哪个数据，那就代表没有父级,直接放在最外层
            r.push(treeArray[i]);
        }
    }
    return r;
}

/**
 * @description 获取节点的所有父节点
 * @param {*} tree
 * @param {*} func
 * @param {*} path
 * @return {*}
 */
export const treeFindPath = (tree, func, name = "id", path = []) => {
    if (!tree) return [];
    for (const data of tree) {
        //* 这里按照你的需求来存放最后返回的内容吧
        path.push(data[name]);
        if (func(data)) return path;
        if (data.children) {
            const findChildren = treeFindPath(data.children, func, name, path);
            if (findChildren.length) return findChildren;
        }
        path.pop();
    }
    return [];
};

/**
 * @description: 拆箱函数,解决tooltip显示问题
 * @param {*} obj
 * @return {*}
 */
export const unwarp = (obj) => obj && (obj.__v_raw || obj.valueOf() || obj);

/**
 * @description:获取所有的el-svg-icon组件名
 * @param {*}
 * @return {*}
 */
export const icons = () => {
    const components = require("@element-plus/icons-vue");
    console.log("🚀 ~ file: index.js ~ line 107 ~ icons ~ e", components);

    const names = [];
    for (const key in components) {
        names.push(components[key].name);
    }
    return names;
};

/**
 * 深拷贝对象
 * @param {*} obj - 要拷贝的对象
 * @returns {*} 拷贝后的对象
 */
export const deepClone = (obj) => {
    if (obj === null || typeof obj !== "object") return obj;
    if (obj instanceof Date) return new Date(obj.getTime());
    if (obj instanceof Array) return obj.map((item) => deepClone(item));
    if (typeof obj === "object") {
        const clonedObj = {};
        for (const key in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, key)) {
                clonedObj[key] = deepClone(obj[key]);
            }
        }
        return clonedObj;
    }
};

/**
 * 防抖函数
 * @param {Function} func - 要防抖的函数
 * @param {number} wait - 等待时间（毫秒）
 * @returns {Function} 防抖后的函数
 */
export const debounce = (func, wait) => {
    let timeout;
    return function executedFunction(...args) {
        const later = () => {
            clearTimeout(timeout);
            func(...args);
        };
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
    };
};

/**
 * 节流函数
 * @param {Function} func - 要节流的函数
 * @param {number} limit - 限制时间（毫秒）
 * @returns {Function} 节流后的函数
 */
export const throttle = (func, limit) => {
    let inThrottle;
    return function executedFunction(...args) {
        if (!inThrottle) {
            func.apply(this, args);
            inThrottle = true;
            setTimeout(() => (inThrottle = false), limit);
        }
    };
};

/**
 * 格式化日期
 * @param {Date|string} date - 日期对象或日期字符串
 * @param {string} format - 格式化模板，默认为 'YYYY-MM-DD HH:mm:ss'
 * @returns {string} 格式化后的日期字符串
 */
export const formatDate = (date, format = "YYYY-MM-DD HH:mm:ss") => {
    const d = new Date(date);
    const year = d.getFullYear();
    const month = String(d.getMonth() + 1).padStart(2, "0");
    const day = String(d.getDate()).padStart(2, "0");
    const hours = String(d.getHours()).padStart(2, "0");
    const minutes = String(d.getMinutes()).padStart(2, "0");
    const seconds = String(d.getSeconds()).padStart(2, "0");

    return format
        .replace("YYYY", year)
        .replace("MM", month)
        .replace("DD", day)
        .replace("HH", hours)
        .replace("mm", minutes)
        .replace("ss", seconds);
};

/**
 * 生成唯一ID
 * @param {number} length - ID长度，默认为8
 * @returns {string} 唯一ID
 */
export const generateId = (length = 8) => {
    const chars =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    let result = "";
    for (let i = 0; i < length; i++) {
        result += chars.charAt(Math.floor(Math.random() * chars.length));
    }
    return result;
};

/**
 * 检查对象是否为空
 * @param {*} obj - 要检查的对象
 * @returns {boolean} 是否为空
 */
export const isEmpty = (obj) => {
    if (obj === null || obj === undefined) return true;
    if (typeof obj === "string") return obj.trim().length === 0;
    if (Array.isArray(obj)) return obj.length === 0;
    if (typeof obj === "object") return Object.keys(obj).length === 0;
    return false;
};

/**
 * 获取对象指定路径的值
 * @param {Object} obj - 对象
 * @param {string} path - 路径，如 'user.name'
 * @param {*} defaultValue - 默认值
 * @returns {*} 获取到的值
 */
export const get = (obj, path, defaultValue = undefined) => {
    const keys = path.split(".");
    let result = obj;

    for (const key of keys) {
        if (result && typeof result === "object" && key in result) {
            result = result[key];
        } else {
            return defaultValue;
        }
    }

    return result;
};

/**
 * 设置对象指定路径的值
 * @param {Object} obj - 对象
 * @param {string} path - 路径，如 'user.name'
 * @param {*} value - 要设置的值
 * @returns {Object} 设置后的对象
 */
export const set = (obj, path, value) => {
    const keys = path.split(".");
    const lastKey = keys.pop();
    let current = obj;
    for (const key of keys) {
        if (!(key in current) || typeof current[key] !== "object") {
            current[key] = {};
        }
        current = current[key];
    }

    current[lastKey] = value;
    return obj;
};
